<!-- 搜索帮助 -->
<template>
  <div>
    <!--输入框-->
    <el-autocomplete
      v-bind="$attrs"
      v-on="$listeners"
      v-model="childValue"
      clearable
      v-if="filterable"
      :fetch-suggestions="querySuggestions"
      :trigger-on-focus="false"
      @select="handleSelectSuggestion"
      @clear="handleClear"
      ref="autoRef"
    >
      <template slot-scope="{ item }">
        {{ item.text }}
      </template>
      <i
        slot="suffix"
        class="el-input__icon el-icon-search"
        @click="handleSelector"
        :class="$attrs.disabled ? 'disabled' : ''"
      ></i>
    </el-autocomplete>
    <el-input
      ref="inputLabel"
      class="input-cursor"
      v-bind="$attrs"
      v-on="$listeners"
      v-model="childLabel"
      @focus="onInputFocus"
      :clearable="clearable"
      @clear="handleClear"
      v-else-if="showLabel"
    >
      <i
        slot="suffix"
        class="el-input__icon el-icon-search"
        @click="handleSelector"
        :class="$attrs.disabled ? 'disabled' : ''"
      ></i>
    </el-input>
    <el-input
      ref="inputValue"
      class="input-cursor"
      v-bind="$attrs"
      v-on="$listeners"
      v-model="childValue"
      @focus="onInputFocus"
      clearable
      @clear="handleClear"
      v-else
    >
      <i
        slot="suffix"
        class="el-input__icon el-icon-search"
        @click="handleSelector"
        :class="$attrs.disabled ? 'disabled' : ''"
      ></i>
    </el-input>
    <!--弹出框-->
    <vxe-modal
      v-model="open"
      :title="dialogTitle || $t('generic.selectPlaceHolder')"
      type="confirm"
      :width="dialogWidth"
      :height="dialogHeight"
      :transfer="true"
      :zIndex="3044"
      resize
      show-zoom
      show-footer
    >
      <template #default>
        <vxe-grid
          ref="xGrid"
          id="dataTableValueHelper"
          class="grid-scrollbar"
          :border="true"
          :stripe="true"
          :show-overflow="true"
          :row-config="{
            isHover: true,
          }"
          :column-config="{
            resizable: true,
          }"
          :height="tableHeight"
          :radio-config="{
            trigger: 'row',
            highlight: true,
          }"
          :columns="
            [
              {
                title: '序号',
                type: 'seq',
                width: 50,
                align: 'center',
              },
            ].concat(columns)
          "
          :pager-config="tablePage"
          :proxy-config="tableProxy"
          :sort-config="{
            remote: true,
            trigger: 'cell',
            defaultSort: defaultSort,
            orders: ['desc', 'asc', null],
          }"
          @cell-dblclick="handleDbSelected"
        >
          <!--使用 form 插槽-->
          <template #form>
            <el-form :model="queryParams" ref="dialogQueryForm" :inline="true">
              <el-form-item
                v-for="domain in dynamicDomains"
                :label="domain.label"
                :key="domain.key"
                :prop="domain.prop"
              >
                <el-input
                  v-model="domain.value"
                  :disabled="domain.disabled"
                  clearable
                  @keyup.enter.native="handleQuery"
                ></el-input>
              </el-form-item>
              <el-form-item>
                <el-button
                  type="primary"
                  icon="el-icon-search"
                  @click="handleQuery"
                  >{{ $t("generic.search") }}</el-button
                >
                <el-button icon="el-icon-refresh" @click="resetQuery">{{
                  $t("generic.reset")
                }}</el-button>
              </el-form-item>
            </el-form>
          </template>
        </vxe-grid>
      </template>
      <template #footer>
        <vxe-button @click="cancel">{{ $t("generic.cancel") }}</vxe-button>
        <vxe-button status="primary" @click="handleSelectionSubmit">{{
          $t("generic.confirm")
        }}</vxe-button>
      </template>
    </vxe-modal>
  </div>
</template>

<script>
export default {
  name: "ValueHelper",
  components: {},
  props: {
    //值
    value: {
      type: [String, Number],
      default: null,
    },
    //是否可搜索
    filterable: {
      type: Boolean,
      default: false,
    },
    //显示value还是label,默认Value（不管显示哪个，实际值还是value）,filterable=true时不支持
    showLabel: {
      type: Boolean,
      default: false,
    },
    //输入框是否显示清空图标
    clearable: {
      type: Boolean,
      default: true,
    },
    //值的配置选项
    valueProps: {
      type: Object,
      default: () => {
        return { value: "value", label: "label" };
      },
    },
    //对话框标题
    dialogTitle: {
      type: String,
      default: undefined,
    },
    //对话框宽度
    dialogWidth: {
      type: String,
      default: "700px",
    },
    //对话框高度
    dialogHeight: {
      type: String,
      default: "470px",
    },
    //对话框高度
    tableHeight: {
      type: [String, Number],
      default: "auto",
    },
    //搜索条件,例子[{key:0,label:'货币编码',prop:'currencyCode'},{key:1,label:'货币名称', prop:'currencyName'},]
    searchCriteria: {
      type: Array,
      default: () => [],
    },
    //额外的查询参数
    otherParam: {
      type: Object,
      default: () => {},
    },
    //搜索方法
    searchMethod: {
      type: Function,
      default: undefined,
    },
    //显示字段,例子[{key: 0,label: '货币编码',prop: 'currencyCode',align: 'center',sortable: true,},
    // { key: 1, label: '货币名称', prop: 'currencyName', sortable: true },]
    columns: {
      type: Array,
      default: () => [],
    },
    //默认的排序列的 prop 和顺序。例子{prop: "name",order: "ascending"}
    defaultSort: {
      type: Object,
      default: () => {},
    },
    //校验方法
    checkMethod: {
      type: Function,
      default: undefined,
    },
    //选项分隔符
    separator: {
      type: String,
      default: "/",
    },
  },
  data() {
    return {
      //选择参数
      queryParams: {},
      //选择值
      childValue: this.value,
      //选择文本
      childLabel: undefined,
      //是否显示弹出层
      open: false,
      // 配置分页信息
      tablePage: {
        background: true,
        pagerCount: 5,
        pageSize: 10,
        pageSizes: [10, 20, 50, 100],
      },
      // 配置数据代理
      tableProxy: {
        autoLoad: false, //是否自动加载查询数据
        sort: true, // 启用排序代理
        props: {
          result: "rows", // 配置响应结果列表字段
          total: "total", // 配置响应结果总页数字段
        },
        ajax: {
          // 接收 Promise 对象
          query: ({ page, sorts, filters }) => {
            //查询
            return this.searchMethod(
              this.buildParams(page, sorts, filters)
            ).then((response) => response);
          },
        },
      },
      // 动态查询参数
      dynamicDomains: [],
    };
  },
  watch: {
    //父组件值变更
    value(val) {
      if (this.childValue !== val) {
        // console.log("value change0:", val, this.childValue, this.childLabel);
        this.childValue = val;
        //有值，非Filterable模式，且是Show label时，获取文本
        if (val && !this.filterable && this.showLabel) {
          // console.log("value change1:", val, this.childValue, this.childLabel);
          this.queryMappingLabel(val);
        } else {
          this.childLabel = undefined;
        }
        // console.log("value change2:", val, this.childValue, this.childLabel);
      } else {
        // console.log("value change3:", val, this.childValue, this.childLabel);
      }
    },
    //搜索条件变更
    searchCriteria(val, oldVal) {
      if (JSON.stringify(val) !== JSON.stringify(oldVal)) {
        this.criteriaToDynamicDomain(val);
      }
    },
  },
  created() {
    //当显示文本模式时，通过初始值获取初始文本
    if (this.value && !this.filterable && this.showLabel) {
      this.queryMappingLabel(this.value);
    }
    //搜索条件转为动态输入框
    this.criteriaToDynamicDomain(this.searchCriteria);
  },
  methods: {
    //构建查询条件
    buildParams(page, sorts, filters) {
      //分页
      const pageParams = {
        pageNum: page.currentPage,
        pageSize: page.pageSize,
        reasonable: true,
      };
      //查询条件
      const selectParams = this.addDynamicDomains(
        pageParams,
        this.dynamicDomains
      );
      // 处理排序条件
      if (sorts && sorts.length > 0) {
        const firstSort = sorts[0];
        if (firstSort) {
          selectParams.orderByColumn = firstSort.property;
          selectParams.isAsc = firstSort.order;
        }
      }
      // 处理筛选条件
      if (filters) {
        filters.forEach(({ property, values }) => {
          selectParams[property] = values.join(",");
        });
      }
      //额外的参数
      if (this.otherParam) {
        for (let key in this.otherParam) {
          selectParams[key] = this.otherParam[key];
        }
      }
      //模糊查询Code
      selectParams.params = { fuzzyQueryCode: true };

      console.log("buildQueryParams: ", selectParams);

      return selectParams;
    },
    /**
     * 输入条件转为动态输入框
     */
    criteriaToDynamicDomain(val) {
      this.dynamicDomains = val.map((item, i) => {
        return {
          key: i,
          label: item.label,
          prop: item.prop,
          value: item.value,
          disabled: item.disabled || false,
        };
      });
    },
    //获取值对应的文本
    queryMappingLabel(val) {
      var conditions = { pageNum: 1, pageSize: 1, reasonable: true };
      conditions[this.valueProps.value] = val;
      this.searchMethod(conditions).then((response) => {
        if (response.rows && response.rows.length > 0) {
          this.childLabel = response.rows[0][this.valueProps.label]; //文本
        }
      });
    },
    //根据用户输入远程搜索(暂时不支持Label)
    querySuggestions(queryString, callback) {
      var conditions = {
        reasonable: true,
        orderByColumn: this.defaultSort.field,
        isAsc: this.defaultSort.order,
        params: { fuzzyQueryCode: true }, //模糊查询Code
      };
      conditions[this.valueProps.value] = queryString; //暂时不支持Label
      //远程查询
      this.searchMethod(conditions).then((response) => {
        //结果转换
        var results = response.rows.map((item, i) => {
          var values = [];
          if (this.columns && this.columns.length > 0) {
            for (var index = 0; index < this.columns.length; index++) {
              values.push(item[this.columns[index].field]);
            }
          } else {
            values.push(item[this.valueProps.value]);
            values.push(item[this.valueProps.label]);
          }
          return {
            value: item[this.valueProps.value], //暂时不支持Label
            text: values.join(this.separator),
            raw: item,
          };
        });
        //结果回调
        callback(results);
      });
    },
    //选择建议
    handleSelectSuggestion(item) {
      this.$emit("selectSubmit", item.raw); //提交事件，传递值给父组件
    },
    //不允许输入框输入,但又支持Clear事件
    onInputFocus(event) {
      if (this.showLabel) {
        this.$refs.inputLabel.blur();
      } else {
        this.$refs.inputValue.blur();
      }
      this.handleSelector();
    },
    //增加动态查询字段
    addDynamicDomains(params, domains) {
      let search = params;
      if (domains && domains.length > 0) {
        for (var i = 0; i < domains.length; i++) {
          search[domains[i].prop] = domains[i].value;
        }
      }
      return search;
    },
    //弹出选择框
    handleSelector() {
      this.open = true;
      this.$nextTick(() => {
        //console.log(this.$refs.xGrid);
        this.$refs.xGrid.commitProxy("query");
      });
    },
    //关闭选择框
    cancel() {
      this.open = false;
    },
    /** 搜索按钮操作 */
    handleQuery() {
      console.log(this.$refs.xGrid);
      // this.queryParams.pageNum = 1;
      this.$refs.xGrid.commitProxy("query");
    },
    /** 重置按钮操作 */
    resetQuery() {
      if (this.dynamicDomains && this.dynamicDomains.length > 0) {
        for (var i = 0; i < this.dynamicDomains.length; i++) {
          this.dynamicDomains[i].value = undefined;
        }
      }
      this.handleQuery();
    },
    /**
     * 双击选择
     */
    handleDbSelected({ row }) {
      this.childValue = row[this.valueProps.value]; //值
      this.childLabel = row[this.valueProps.label]; //文本
      this.$emit("input", row[this.valueProps.value]); //传递值给父组件
      this.$emit("selectSubmit", row); //提交事件，传递值给父组件
      this.cancel();
    },
    /**
     * 点击确定提交
     */
    handleSelectionSubmit() {
      const selectionObject = this.$refs.xGrid.getRadioRecord();
      if (selectionObject) {
        this.childValue = selectionObject[this.valueProps.value]; //值
        this.childLabel = selectionObject[this.valueProps.label]; //文本
        this.$emit("input", selectionObject[this.valueProps.value]); //传递值给父组件
        this.$emit("selectSubmit", selectionObject); //提交事件，传递值给父组件
        this.cancel();
      } else {
        this.$modal.alertWarning("请选择任意一行");
      }
    },
    //清空事件
    handleClear() {
      if (this.filterable) {
        this.$refs.autoRef.activated = true;  //使用clearable清除,点击输入框下拉条件不再显示
      }
      this.$emit("clearSelect");
    },
  },
};
</script>
<style lang="scss" scoped>
.disabled {
  pointer-events: none;
}
::v-deep {
  .el-input__suffix {
    &-inner {
      flex-direction: row-reverse;
      -webkit-flex-direction: row-reverse;
      display: flex;
    }
  }

  .el-icon-search {
    position: relative;
    &:hover {
      cursor: pointer;
      color: rgb(147, 149, 153);
    }
    &::after {
      width: 1px;
      height: 50%;
      left: -1.5px;
      position: absolute;
      top: 25%;
      background-color: rgb(233, 233, 233);
    }
  }
}
.input-cursor ::v-deep .el-input__inner {
  cursor: pointer;
}

/*滚动条整体部分*/
.grid-scrollbar ::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
/*滚动条的轨道*/
.grid-scrollbar ::-webkit-scrollbar-track {
  background-color: #ffffff;
}
/*滚动条里面的小方块，能向上向下移动*/
.grid-scrollbar ::-webkit-scrollbar-thumb {
  background-color: #bfbfbf;
  border-radius: 5px;
  border: 1px solid #f1f1f1;
  box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}
.grid-scrollbar ::-webkit-scrollbar-thumb:hover {
  background-color: #a8a8a8;
}
.grid-scrollbar ::-webkit-scrollbar-thumb:active {
  background-color: #787878;
}
/*边角，即两个滚动条的交汇处*/
.grid-scrollbar ::-webkit-scrollbar-corner {
  background-color: #ffffff;
}
</style>
